<?php

namespace app\middleware;

use app\admin\system\service\AdminService;
use app\common\controller\BaseAdminController;
use common\service\AuthService;
use common\service\JwtService;
use ReflectionClass;
use ReflectionException;
use support\exception\BadException;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use Webman\Http\Request;
use Webman\Http\Response;
use Webman\MiddlewareInterface;

class AuthMiddleware implements MiddlewareInterface
{
    const ALL_AUTH = "*";

    /**
     * @param Request $request
     * @param callable $handler
     * @return Response
     * @throws BadException
     * @throws ReflectionException
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function process(Request $request, callable $handler): Response
    {
        // 通过反射获取控制器哪些方法不需要登录
        $controller = new ReflectionClass($request->controller);
        //如果没有继承BaseAdminController 就不走后续的逻辑了 不验证登录或者鉴权
        if (!$controller->isSubclassOf(BaseAdminController::class)) {
            return $handler($request);
        }

        $prop = $controller->getDefaultProperties();
        $noNeedLogin = $prop['noNeedLogin'] ?? [];
        $noNeedRight = $prop['noNeedRight'] ?? [];
        $method = $controller->getMethod($request->action);
        if (in_array(self::ALL_AUTH, $noNeedLogin) || in_array($request->action, $noNeedLogin)) {
            // 访问的方法不需要登录
            return $handler($request);
        }
        $user = JwtService::checkJwtToken('admin');
        if (!$user) {
            throw new BadException("登录异常", 401);
        }
        $uid = $user['id'];
        $request->uid = $uid;

        if (in_array(self::ALL_AUTH, $noNeedRight) || in_array($request->action, $noNeedRight)) {
            return $handler($request);
        }
        $authority = AdminService::getAuthority($uid);
        if (in_array(self::ALL_AUTH, $authority)) {
            //超级权限 不需要鉴权
            return $handler($request);
        }
        // 访问的方法需要鉴权
        $flag = AuthService::checkAuth($request, $authority, $method);

        if (!$flag) {
            throw new BadException("当前登录人无该接口权限:" . $request->path(), 401001);
        }
        return $handler($request);
    }



}
